package cn.cdeden.knowledge.controller.team;

import cn.cdeden.common.core.domain.R;
import cn.cdeden.common.core.utils.page.TableDataInfo;
import cn.cdeden.common.satoken.utils.LoginHelper;
import cn.cdeden.knowledge.domain.SysLogPerm;
import cn.cdeden.knowledge.domain.TeamFilesTree;
import cn.cdeden.knowledge.domain.TeamRole;
import cn.cdeden.knowledge.domain.dto.TeamRelevanceRoleDto;
import cn.cdeden.knowledge.domain.dto.TeamRelevanceRoleQueryParam;
import cn.cdeden.knowledge.domain.dto.TeamRoleDto;
import cn.cdeden.knowledge.domain.vo.TeamPermVo;
import cn.cdeden.knowledge.enums.*;
import cn.cdeden.knowledge.service.SysDocLogService;
import cn.cdeden.knowledge.service.TeamFilesTreeService;
import cn.cdeden.knowledge.service.TeamRelevanceRoleService;
import cn.cdeden.knowledge.service.TeamRoleService;
import cn.cdeden.system.api.RemoteUserService;
import com.alibaba.fastjson.JSONArray;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Chen
 * @date 2023-11-29
 **/
@RestController
@RequiredArgsConstructor
//@Api(tags = "团队角色关联表管理")
@RequestMapping("/api/teamRelevanceRole")
public class TeamRelevanceRoleController {

    private final TeamRoleService teamRoleService;

    private final TeamRelevanceRoleService teamRelevanceRoleService;
    private final TeamFilesTreeService teamFilesTreeService;
    private final SysDocLogService sysDocLogService;
    @DubboReference
    private final RemoteUserService remoteUserService;

//    @Log("查询团队文档权限")
//    @ApiOperation("查询团队文档权限")
    @GetMapping(value = "/query")
    @ResponseBody
    public R query(TeamRelevanceRoleQueryParam query, Pageable pageable) {
        TableDataInfo<TeamRelevanceRoleDto> teamRelevanceRoleDtoPageInfo = teamRelevanceRoleService.queryAll(query, pageable);
        return R .ok(teamRelevanceRoleDtoPageInfo);
    }

//    @Log("测试")
//    @ApiOperation("测试")
    @PostMapping(value = "/test")
    @ResponseBody
    public R  test(@RequestParam String teamId,@RequestParam List<String> ids,@RequestParam Long userId) {
        return R.ok(teamRelevanceRoleService.checkPermissionByIds(teamId,ids,userId, TeamParamEnum.CHECK.getParam()));
    }


    /**
     * 如果是查询多个文档的权限，返回的就是他们公共拥有的权限。
     *
     * @param teamPermVo
     * @return
     */
//    @Log("查询用户文档权限")
//    @ApiOperation("查询用户文档权限")
    @PostMapping(value = "/queryPermByUser")
    @ResponseBody
    public R queryPermByUser(@RequestBody TeamPermVo teamPermVo) {
        List<String> treeNodeIds = teamPermVo.getTreeNodeIds();
        String teamId = teamPermVo.getTeamId();
        String userId = teamPermVo.getUserId();

        if (treeNodeIds.size() == 1) {
            List<TeamRelevanceRoleDto> teamRelevanceRoleDtos = teamRelevanceRoleService.getRole(treeNodeIds.get(0), teamId, remoteUserService.getUserInfo(Long.valueOf(userId)));
            List<TeamRole> teamRoles = new ArrayList<>();
            for (TeamRelevanceRoleDto teamRelevanceRoleDto : teamRelevanceRoleDtos) {
                teamRoles.add(teamRoleService.getById(teamRelevanceRoleDto.getRoleId()));
            }
            return R.ok(teamRoles);
        }
        List<String> paramsList = new ArrayList<>();
        List<String> tempList = null;
        //多个文档时查询他们拥有的共有权限
        for (String treeNodeId : treeNodeIds) {
            List<TeamRelevanceRoleDto> teamRelevanceRoleDtos = teamRelevanceRoleService.getRole(treeNodeId, teamId, remoteUserService.getUserInfo(Long.valueOf(userId)));
            List<TeamRole> teamRoles = new ArrayList<>();
            for (TeamRelevanceRoleDto teamRelevanceRoleDto : teamRelevanceRoleDtos) {
                teamRoles.add(teamRoleService.getById(teamRelevanceRoleDto.getRoleId()));
            }
            for (TeamRole teamRole : teamRoles) {
                String params = teamRole.getParams();
                JSONArray jsonArray = JSONArray.parseArray(params);
                tempList = paramsList;
                paramsList = new ArrayList<>();
                if (tempList.size() == 0) {
                    for (Object o : jsonArray) {
                        paramsList.add(String.valueOf(o));
                        tempList.add(String.valueOf(o));
                    }
                } else {
                    for (Object o : jsonArray) {
                        for (String s : tempList) {
                            if (String.valueOf(o).equals(s)) {
                                paramsList.add(String.valueOf(o));
                            }
                        }
                    }
                }
            }
        }
        TeamRole teamRole = new TeamRole();
        teamRole.setParams(JSONArray.toJSONString(paramsList));
        return R.ok(teamRole);
    }

//    @Log("添加团队文档权限")
//    @ApiOperation("添加团队文档权限")
    @PostMapping(value = "/add")
    @ResponseBody
    public R add(@RequestBody List<TeamRelevanceRoleDto> teamRelevanceRoleDtos) {
        if (teamRelevanceRoleDtos.size() == 0) {
            throw new RuntimeException("请选择成员！");
        }
        String treeNodeId = teamRelevanceRoleDtos.get(0).getTreeNodeId();
        String teamId = teamRelevanceRoleDtos.get(0).getTeamId();
        if (!teamRelevanceRoleService.checkPermission(treeNodeId, teamRelevanceRoleDtos.get(0).getTeamId(), LoginHelper.getLoginUser(), TeamParamEnum.JURISDICTION.getParam())) {
            return R.fail(ResultEnum.PERM_ERROR.getNum(), "无分配权限！");
        }
        List<TeamRoleDto> roles = teamRoleService.getRole(teamId);
        String roleId = null;
        Integer roleRank = 1;
        for (TeamRoleDto role : roles) {
            if (role.getRank() > roleRank){
                roleId = String.valueOf(role.getId());
            }
        }
        for (TeamRelevanceRoleDto teamRelevanceRoleDto : teamRelevanceRoleDtos) {
            //跨文档权限继承
            List<TeamFilesTree> teamFilesTrees = teamFilesTreeService.selectSuperiorAll(teamRelevanceRoleDto.getTreeNodeId());
            for (TeamFilesTree teamFilesTree : teamFilesTrees) {
                if (teamFilesTree.getType().equals(TreeTypeEnum.HEAD.getType())) {
                    continue;
                }
                //查询上级文档是否有该用户权限
                if (teamRelevanceRoleService.getRelevanceRoleByObject(String.valueOf(teamFilesTree.getId()), teamRelevanceRoleDto.getTeamId(), teamRelevanceRoleDto.getObjectId(), teamRelevanceRoleDto.getObjectType()).size() > 0) {
                    //该用户在此文档下已有该权限角色 跳过添加该对象
                    continue;
                }
                TeamRelevanceRoleDto teamRelevanceRoleDtoInsert = new TeamRelevanceRoleDto();
                //标记为添加的权限
                if (!treeNodeId.equals(teamFilesTree.getId().toString())){
                    teamRelevanceRoleDtoInsert.setRoleId(roleId);
                }else {
                    teamRelevanceRoleDtoInsert.setRoleId(teamRelevanceRoleDto.getRoleId());
                }
                teamRelevanceRoleDtoInsert.setCreateId(String.valueOf(LoginHelper.getUserId()));
                teamRelevanceRoleDtoInsert.setCreateTime(new Date());
                teamRelevanceRoleDtoInsert.setObjectId(teamRelevanceRoleDto.getObjectId());
                teamRelevanceRoleDtoInsert.setObjectType(teamRelevanceRoleDto.getObjectType());
                teamRelevanceRoleDtoInsert.setTeamId(teamId);
                teamRelevanceRoleDtoInsert.setIsExtend(0);
                teamRelevanceRoleDtoInsert.setTreeNodeId(String.valueOf(teamFilesTree.getId()));
                teamRelevanceRoleService.insert(teamRelevanceRoleDtoInsert);
                //创建日志
                createPermLog(treeNodeId, teamFilesTree);
            }
        }

        //同步至下级权限
        syncJuniorPerm(treeNodeId);
        return R.ok();
    }

    private void syncJuniorPerm(String treeNodeId) {

        TeamRelevanceRoleQueryParam teamRelevanceRoleQueryParam = new TeamRelevanceRoleQueryParam();
        teamRelevanceRoleQueryParam.setTreeNodeId(treeNodeId);

        //获取需要继承的权限
        List<TeamRelevanceRoleDto> relevanceRoleDtoList = teamRelevanceRoleService.getRelevanceRoleByTreeNodeId(treeNodeId);

        //查询所有下级文档
        List<TeamFilesTree> teamFilesTrees = teamFilesTreeService.selectJuniorAll(treeNodeId);
        for (TeamFilesTree filesTree : teamFilesTrees) {
            //获取该文档的所有权限
            List<TeamRelevanceRoleDto> relevanceRoleByTreeNodeId = teamRelevanceRoleService.getRelevanceRoleByTreeNodeId(String.valueOf(filesTree.getId()));

            //删除所有者以外权限
            TeamRelevanceRoleDto ownerDto = null; //该文档的所有者对象
            for (TeamRelevanceRoleDto teamRelevanceRoleDto : relevanceRoleByTreeNodeId) {
                int rank = teamRoleService.getById(teamRelevanceRoleDto.getRoleId()).getRank();
                if (rank == 1) {
                    teamRelevanceRoleDto.setRoleRank(rank);
                    ownerDto = teamRelevanceRoleDto;
                    break;
                }
            }
            relevanceRoleByTreeNodeId.removeIf(r -> r.getRoleRank() == 1);
            teamRelevanceRoleService.removeByIds(relevanceRoleByTreeNodeId);

            List<TeamRelevanceRoleDto> permLogList = new ArrayList<>();
            //添加给该文档
            for (TeamRelevanceRoleDto teamRelevanceRoleDto : relevanceRoleDtoList) {
                //跳过指定的权限中含有该文档所有者的情况
                if (teamRelevanceRoleDto.getObjectId().equals(ownerDto.getObjectId()) && teamRelevanceRoleDto.getObjectType() == PermTypeEnum.USER.getPermTypeCode()) {
                    permLogList.add(ownerDto);
                } else {
                    teamRelevanceRoleDto.setTreeNodeId(String.valueOf(filesTree.getId()));
                    permLogList.add(teamRelevanceRoleDto);
                    //标记为继承的权限
                    teamRelevanceRoleDto.setIsExtend(1);
                    teamRelevanceRoleDto.setId(null);
                    teamRelevanceRoleService.insert(teamRelevanceRoleDto);
                }
            }
            //创建日志
            setPermLogByPermList(filesTree, permLogList);

        }
    }

    private void createPermLog(String treeNodeId, TeamFilesTree teamFilesTree) {
        List<TeamRelevanceRoleDto> list = teamRelevanceRoleService.getRelevanceRoleByTreeNodeId(treeNodeId);
        setPermLogByPermList(teamFilesTree, list);
    }

    private void setPermLogByPermList(TeamFilesTree filesTree, List<TeamRelevanceRoleDto> teamRelevanceRoleDtoList) {
        for (TeamRelevanceRoleDto relevanceRoleDto : teamRelevanceRoleDtoList) {
            relevanceRoleDto.setPermJson(teamRoleService.getById(relevanceRoleDto.getRoleId()).getParams());
        }
        List<SysLogPerm> collect = teamRelevanceRoleDtoList.stream().map(res -> new SysLogPerm(res.getObjectId(), res.getObjectType(), res.getPermJson(), res.getRoleId())).collect(Collectors.toList());
        sysDocLogService.createPermLog(String.valueOf(filesTree.getId()), null, TreeEnum.TEAM, OperationEnum.UPDATE.judgmentType(filesTree.getType()), filesTree.getRealName(), filesTree.getPath(), null, collect);
    }

//    @Log("修改文档角色权限")
//    @ApiOperation("修改文档角色权限")
    @PostMapping(value = "/updateUserRoleType")
    @Transactional(rollbackFor = Exception.class)
    public R updateUserRoleType(@RequestBody List<TeamRelevanceRoleDto> teamRelevanceRoleDtos) {

        String treeNodeId = teamRelevanceRoleDtos.get(0).getTreeNodeId();
        String teamId = teamRelevanceRoleDtos.get(0).getTeamId();
        if (!teamRelevanceRoleService.checkPermission(treeNodeId, teamId, LoginHelper.getLoginUser(), TeamParamEnum.JURISDICTION.getParam())) {
            return R.fail(ResultEnum.PERM_ERROR.getNum(), "无分配权限！");
        }
        for (TeamRelevanceRoleDto teamRelevanceRoleDto : teamRelevanceRoleDtos) {
            teamRelevanceRoleService.updateRole(treeNodeId, teamRelevanceRoleDto.getObjectId(), teamRelevanceRoleDto.getObjectType(), teamRelevanceRoleDto.getRoleId());
        }

        //创建日志
        TeamFilesTree teamFilesTree = teamFilesTreeService.getById(treeNodeId);
        createPermLog(treeNodeId, teamFilesTree);

        return R.ok(null);
    }

//    @Log("删除团队文档权限")
//    @ApiOperation("删除团队文档权限")
    @PostMapping(value = "/delete")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@RequestBody List<TeamRelevanceRoleDto> teamRelevanceRoleDtos) {
        for (TeamRelevanceRoleDto teamRelevanceRoleDto : teamRelevanceRoleDtos) {
            String treeNodeId = teamRelevanceRoleDto.getTreeNodeId();
            if (!teamRelevanceRoleService.checkPermission(treeNodeId, teamRelevanceRoleDto.getTeamId(), LoginHelper.getLoginUser(), TeamParamEnum.JURISDICTION.getParam())) {
                return R.fail(ResultEnum.PERM_ERROR.getNum(), "无分配权限！");
            }
            //删除下级继承的该权限
            //查询所有下级文档
            List<TeamFilesTree> teamFilesTrees = teamFilesTreeService.selectJuniorAll(treeNodeId);
            for (TeamFilesTree teamFilesTree : teamFilesTrees) {
                teamRelevanceRoleService.removeExtend(teamFilesTree.getId(),teamRelevanceRoleDto.getObjectId());
            }

            //创建日志
            TeamFilesTree teamFilesTree = teamFilesTreeService.getById(treeNodeId);
            createPermLog(treeNodeId, teamFilesTree);
            teamRelevanceRoleService.removeById(teamRelevanceRoleDto.getId());
        }
        return R.ok(true);
    }

}
